import math
from typing import List
from common.params import SoftParams
from model.soft.soft_common import AxialForceResult, data_init
from model.soft.cable_fluid import get_cable_total_force
from model.soft.tool_fluid import get_tool_total_force


# 计算上提的轴力 在内部计算轴力的过程中加入其他类型的流体阻力，仪器的液体阻力除以L1，电缆（井底的）的是除以D-L1的
def calc_uni(params: SoftParams, cur: AxialForceResult, pre: AxialForceResult,
             _list_: List[AxialForceResult], is_Not_add_resistance: bool) -> AxialForceResult:
    # 本次计算全井深度
    D: float = _list_[-1].depth
    params.L1 = round(params.L1)
    tool_fluid: float = get_tool_total_force(params) / params.L1
    cable_fluid: float = get_cable_total_force(params) / (params.L_oh - params.L1)
    # 测井仪器的单位浮重
    w1: float = params.w1
    # 电缆的单位浮重
    w2: float = params.w2
    # 先根据上一个节点的值,计算出来当前的 f
    factor_b: float = math.cos(math.radians(pre.inclination))
    if is_Not_add_resistance == True:
        if D - params.L1 <= cur.depth < D:
            # print(cur.depth)
            f: float = w1 * factor_b + params.get_mu_pull(cur.depth) * pre.N + pre.F - tool_fluid
            cur.F = f
            n: float = calc_n(D, params, cur)
            cur.N = n
        elif 0 <= cur.depth < D - params.L1:
            f: float = w2 * factor_b + params.get_mu_pull(cur.depth) * pre.N + pre.F - cable_fluid
            cur.F = f
            n: float = calc_n(D, params, cur)
            cur.N = n
    else:
        if D - params.L1 <= cur.depth < D:
            # print(cur.depth)
            f: float = w1 * factor_b + params.get_mu_pull(cur.depth) * pre.N + pre.F
            cur.F = f
            n: float = calc_n(D, params, cur)
            cur.N = n
        elif 0 <= cur.depth < D - params.L1:
            f: float = w2 * factor_b + params.get_mu_pull(cur.depth) * pre.N + pre.F
            cur.F = f
            n: float = calc_n(D, params, cur)
            cur.N = n
    # print("从{}开始迭代到当前深度{}的CF:{}, CN: {},PF: {}, PN: {}".format(D, cur.depth, cur.F, cur.N, pre.F, pre.N))
    return cur


# 基于当前节点求解N
# cur.F 已知
def calc_n(D: float, params: SoftParams, cur: AxialForceResult) -> float:
    # 测井仪器的单位浮重
    w1: float = params.w1
    # 电缆的单位浮重
    w2: float = params.w2
    params.L1 = round(params.L1)

    factor_a: float = cur.azimuth_rate
    factor_b: float = math.sin(math.radians(cur.inclination))
    factor_c: float = cur.inclination_rate
    if (cur.depth > D - params.L1) and (cur.depth <= D):
        factor_d: float = cur.F * factor_a * factor_b
        factor_e: float = cur.F * factor_c
        n: float = math.sqrt(math.pow(factor_d, 2) + math.pow(factor_e + w1 * factor_b, 2))
        return n
    # 大于等于 0 @TODO
    elif (cur.depth > 0) and (cur.depth <= D - params.L1):
        factor_d: float = cur.F * factor_a * factor_b
        factor_e: float = cur.F * factor_c
        n: float = math.sqrt(math.pow(factor_d, 2) + math.pow(factor_e + w2 * factor_b, 2))
        return n
    # 未命中返回 0.0
    return 0.0
    # return cur.N


# 轴力迭代数据
def axial_force_build(params: SoftParams, _list_: List[AxialForceResult], is_Not_add_resistance: bool) -> List[AxialForceResult]:
    # 长度
    data_len = len(_list_)
    # 本次迭代深度 -1 就是取最后一个
    D: float = _list_[-1].depth
    _list_[-1].F = 0.0
    # N 的值需要基于 F 算出来
    _list_[-1].N = calc_n(D, params, _list_[-1])
    # 边界条件也需要
    for i in range(data_len - 2, -1, -1):
        _list_[i] = calc_uni(params, _list_[i], _list_[i + 1], _list_, is_Not_add_resistance)
        # print(JsonUtil.obj2str(_list_[i]))
    return _list_


# 执行获取计算结果 & 只需要从最大深度开始迭代的结果
def run(params: SoftParams, _list_, is_Not_add_resistance: bool) -> List[AxialForceResult]:
    # 数据预处理
    result_arr: List[AxialForceResult] = data_init(_list_)
    result: List[AxialForceResult] = axial_force_build(params, result_arr, is_Not_add_resistance)
    # for item in result:
    #     print("深度:{} 的轴力为:{} 接触力 {}".format(item.depth, item.F, item.N))
    return result





